﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Caching;

namespace XMK.Utils
{
        /// <summary>
        /// 缓存处理类
        /// </summary>
        public class CacheHelper
        {

            /// <summary>
            /// 读取缓存
            /// </summary>
            /// <param name="CacheKey">key名</param>
            /// <returns>缓存对象</returns>
            public static object GetCache(string cacheKey)
            {
                return HttpRuntime.Cache[cacheKey];
            }


            /// <summary>
            /// 读取缓存-若空则设置缓存值
            /// </summary>
            /// <param name="cacheKey">缓存ID</param>
            /// <param name="expire">过期时间</param>
            /// <param name="action">当缓存为空时的动作</param>
            /// <returns></returns>
            public static object GetCache(string cacheKey, DateTime expire, Func<object> action)
            {
                object o = GetCache(cacheKey);
                if (o == null)
                {
                    o = action.Invoke();
                    SetCache(cacheKey, o, expire);
                }
                return o;
            }

            /// <summary>
            /// 设置缓存
            /// </summary>
            /// <param name="cacheKey">key名</param>
            /// <param name="objObject">要被缓存的对象</param>
            public static void SetCache(string cacheKey, object objObject)
            {
                if (objObject != null)
                {
                    HttpRuntime.Cache.Insert(cacheKey, objObject);
                }
                else
                {
                    RemoveCache(cacheKey);
                }
            }

            /// <summary>
            /// 设置绝对到期缓存
            /// </summary>
            /// <param name="cacheKey">key名</param>
            /// <param name="objObject">要被缓存的对象</param>
            /// <param name="expire">过期时间</param>
            public static void SetCache(string cacheKey, object objObject, DateTime expire)
            {
                if (objObject != null)
                {
                    HttpRuntime.Cache.Insert(cacheKey, objObject, null, expire, Cache.NoSlidingExpiration);
                }
                else
                {
                    RemoveCache(cacheKey);
                }
            }

            /// <summary>
            /// 设置滑动过期缓存
            /// </summary>
            /// <param name="cacheKey"></param>
            /// <param name="cacheValue"></param>
            /// <param name="slidingExpireTime"></param>
            public static void SetCache(string cacheKey, object cacheValue, TimeSpan slidingExpireTime)
            {
                if (cacheValue != null)
                {
                    HttpRuntime.Cache.Insert(cacheKey, cacheValue, null, Cache.NoAbsoluteExpiration, slidingExpireTime);
                }
                else
                {
                    RemoveCache(cacheKey);
                }
            }

            /// <summary>
            /// 设置绝对过期缓存
            /// </summary>
            /// <param name="cacheKey"></param>
            /// <param name="cacheValue"></param>
            /// <param name="expire"></param>
            /// <param name="beforeRemoveCallback">缓存移除前的操作</param>
            public static void SetCache(string cacheKey, object cacheValue, DateTime expire, CacheItemRemovedCallback beforeRemoveCallback)
            {
                if (cacheValue != null)
                {
                    HttpRuntime.Cache.Insert(cacheKey, cacheValue, null, expire, Cache.NoSlidingExpiration, CacheItemPriority.Default, beforeRemoveCallback);
                }
                else
                {
                    RemoveCache(cacheKey);
                }
            }

            /// <summary>
            /// 根据键名清除缓存
            /// </summary>
            /// <param name="keys">key名</param>
            public static void RemoveCache(string cacheKey)
            {
                HttpRuntime.Cache.Remove(cacheKey);
            }

            
    }
    /// <summary>
    /// 缓存帮助类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CacheHelper<T> where T:class
    {
        /// <summary>
        /// 线程同步锁
        /// </summary>
        private static Object CacheLocker = new Object();
        /// <summary>
        /// 获取保存对象的委托
        /// </summary>
        /// <returns></returns>
        public delegate T SetCacheValue();
        /// <summary>
        /// 取得缓存值
        /// </summary>
        /// <param name="cacheKey">缓存键值</param>
        /// <param name="fun">获取需保存对象的获取委托</param>
        /// <returns>缓存中的对象</returns>
        public static T GetCacheValue(string cacheKey, SetCacheValue fun)
        {
            T t = HttpRuntime.Cache[cacheKey] as T;
            if (t == null)
            {
                t = fun();
                HttpRuntime.Cache[cacheKey] = t;
            }
            return t;
        }
        /// <summary>
        /// 取得缓存值，该缓存仅保存到指定的时间
        /// </summary>
        /// <param name="cacheKey">缓存键值</param>
        /// <param name="fun">获取需保存对象的获取委托</param>
        /// <param name="expire">过期时间</param>
        /// <returns>缓存中的对象</returns>
        public static T GetCacheValue(string cacheKey, DateTime expire, SetCacheValue fun)
        {
            T t = HttpRuntime.Cache[cacheKey] as T;
            if (t == null)
            {
                t = fun();
                //由于此处需要加锁，而不需要过期时间的方法不加锁，所以两个方法的代码没有合并
                lock (CacheLocker)
                {
                    if(HttpRuntime.Cache[cacheKey] != null)
                        HttpRuntime.Cache.Insert(cacheKey, t, null, expire, TimeSpan.Zero);
                }
            }
            return t;
        }
        /// <summary>
        /// 仅获取缓存值
        /// </summary>
        /// <param name="cacheKey">缓存键值</param>
        /// <returns>缓存中的对象</returns>
        public static T GetCacheValue(string cacheKey)
        {
            return HttpRuntime.Cache[cacheKey] as T;
        }
        /// <summary>
        /// 加入到缓存中
        /// </summary>
        /// <param name="cacheKey">缓存键值</param>
        /// <param name="fun">获取需保存对象的获取委托</param>
        public static void SetCache(string cacheKey, SetCacheValue fun)
        {
            SetCache(cacheKey, fun());
        }
        /// <summary>
        /// 加入到缓存中
        /// </summary>
        /// <param name="cacheKey">缓存键值</param>
        /// <param name="t">需缓存的对象</param>
        public static void SetCache(string cacheKey, T t)
        {
            HttpRuntime.Cache[cacheKey] = t;
        }
    }


}
